//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.aidong.dao.base;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

public abstract class BaseDao<T, PK extends Serializable> {
    protected Class<T> entityClass;

    protected BaseDao() {
        Type type = this.getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            this.entityClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
        }

    }

    protected abstract Session getSession();

    public PK add(T po) {
        return (PK) this.getSession().save(po);
    }

    public void update(T po) {
        this.getSession().update(po);
    }

    public int updateByHql(String hql, Object... params) {
        Query query = this.getSession().createQuery(hql);
        this.setParameters(query, params);
        return query.executeUpdate();
    }

    public int updateBySql(String sql, Object... params) {
        SQLQuery query = this.getSession().createSQLQuery(sql);
        this.setParameters(query, params);
        return query.executeUpdate();
    }

    public void deleteById(PK id) {
        this.getSession().delete(this.getById(id));
    }

    public void delete(T po) {
        this.getSession().delete(po);
    }

    public T getById(PK id) {
        return this.getSession().get(this.entityClass, id);
    }

    public boolean exists(PK id) {
        return this.getById(id) != null;
    }

    protected void flush() {
        this.getSession().flush();
    }

    protected void clear() {
        this.getSession().clear();
    }

    public T getByWhere(String sqlww, Object... params) {
        List<T> list = this.queryList(sqlww, params, (OrderSet) null, 1);
        return list != null && list.size() > 0 ? list.get(0) : null;
    }

    public <T> T getBySql(Class<T> clazz, String sql, Object... params) {
        List<T> list = this.queryListBySql(clazz, sql, params);
        return list != null && list.size() > 0 ? list.get(0) : null;
    }

    public List<T> queryList(T po, OrderSet orders, int maxRow) {
        ArrayList params = new ArrayList();
        String sqlww = this.objectToSql(po, params, (String) null);
        return this.queryList(sqlww, params.toArray(), orders, maxRow);
    }

    public List<T> queryList(T po, OrderSet orders) {
        return this.queryList(po, orders, -1);
    }

    public List<T> queryList(ConditionMap condition, OrderSet orders, int maxRow) {
        ArrayList params = new ArrayList();
        String sqlww = condition.toSql(params);
        return this.queryList(sqlww, params.toArray(), orders, maxRow);
    }

    public List<T> queryList(ConditionMap condition, OrderSet orders) {
        return this.queryList((ConditionMap) condition, orders, -1);
    }

    protected List<T> queryList(String sqlww, Object[] params, OrderSet orders, int maxRow) {
        Session session = this.getSession();
        Query query = this.getQuery(session, sqlww, params, orders, false);
        if (maxRow > 0) {
            query.setMaxResults(maxRow);
        }
        return query.list();
    }

    public List<T> queryListBySql(String sql, Object... params) {
        Session session = this.getSession();
        SQLQuery query = session.createSQLQuery(sql);
        this.setParameters(query, params);
        query.addEntity(this.entityClass);
        return query.list();
    }

    public void queryPageList(Pagination<T> pagination, T po, OrderSet orders) {
        ArrayList params = new ArrayList();
        String sqlww = this.objectToSql(po, params, (String) null);
        this.queryPageList(pagination, sqlww, params.toArray(), orders);
    }

    public void queryPageList(Pagination<T> pagination, ConditionMap condition, OrderSet orders) {
        ArrayList params = new ArrayList();
        String sqlww = condition.toSql(params);
        this.queryPageList(pagination, sqlww, params.toArray(), orders);
    }

    protected void queryPageList(Pagination<T> pagination, String sqlww, Object[] params, OrderSet orders) {
        if (pagination != null) {
            Session session = this.getSession();
            Query query;
            if (pagination.getTotalCount() <= 0) {
                query = this.getQuery(session, sqlww, params, orders, true);
                pagination.setTotalCount(((Number) query.uniqueResult()).intValue());
            }

            if (pagination.getPageNo() < 1) {
                pagination.setPageNo(1);
            }

            if (pagination.getPageSize() < 1) {
                pagination.setPageSize(10);
            }

            pagination.setPageCount((pagination.getTotalCount() + pagination.getPageSize() - 1) / pagination.getPageSize());
            query = this.getQuery(session, sqlww, params, orders, false);
            query.setFirstResult(pagination.getPageSize() * (pagination.getPageNo() - 1));
            query.setMaxResults(pagination.getPageSize());
            pagination.setResultList(query.list());
        }
    }

    public void queryPageListBySql(Pagination<T> pagination, String sql, Object... params) {
        if (pagination != null) {
            Session session = this.getSession();
            SQLQuery query;
            if (pagination.getTotalCount() <= 0) {
                int n = sql.toLowerCase().lastIndexOf("order");
                query = session.createSQLQuery("select count(*) from (" + (n > 0 ? sql.substring(0, n) : sql) + ") as tt");
                this.setParameters(query, params);
                pagination.setTotalCount(((Number) query.uniqueResult()).intValue());
            }

            if (pagination.getPageNo() < 1) {
                pagination.setPageNo(1);
            }

            if (pagination.getPageSize() < 1) {
                pagination.setPageSize(10);
            }

            pagination.setPageCount((pagination.getTotalCount() + pagination.getPageSize() - 1) / pagination.getPageSize());
            query = session.createSQLQuery(sql);
            this.setParameters(query, params);
            query.addEntity(this.entityClass);
            query.setFirstResult(pagination.getPageSize() * (pagination.getPageNo() - 1));
            query.setMaxResults(pagination.getPageSize());
            pagination.setResultList(query.list());
        }
    }

    public <O> List<O> queryListBySql(Class<O> clazz, String sql, Object... params) {
        SQLQuery query = this.getSession().createSQLQuery(sql);
        this.setParameters(query, params);
        query.setResultTransformer(new BeanTransformer(clazz));
        return query.list();
    }

    public <O> void queryPageListBySql(Class<O> clazz, Pagination<O> pagination, String sql, Object... params) {
        if (pagination != null) {
            Session session = this.getSession();
            SQLQuery query;
            if (pagination.getTotalCount() <= 0) {
                int n = sql.toLowerCase().lastIndexOf("order by");
                query = session.createSQLQuery("select count(*) from (" + (n > 0 ? sql.substring(0, n) : sql) + ") as tt");
                this.setParameters(query, params);
                pagination.setTotalCount(((Number) query.uniqueResult()).intValue());
            }

            if (pagination.getPageNo() < 1) {
                pagination.setPageNo(1);
            }

            if (pagination.getPageSize() < 1) {
                pagination.setPageSize(10);
            }

            pagination.setPageCount((pagination.getTotalCount() + pagination.getPageSize() - 1) / pagination.getPageSize());
            query = session.createSQLQuery(sql);
            this.setParameters(query, params);
            query.setResultTransformer(new BeanTransformer(clazz));
            query.setFirstResult(pagination.getPageSize() * (pagination.getPageNo() - 1));
            query.setMaxResults(pagination.getPageSize());
            pagination.setResultList(query.list());
        }
    }

    public List<Map<String, Object>> queryMapListBySql(String sql, Object... params) {
        SQLQuery query = this.getSession().createSQLQuery(sql);
        this.setParameters(query, params);
        query.setResultTransformer(new MapTransformer());
        return query.list();
    }

    public void queryPageMapListBySql(Pagination<Map<String, Object>> pagination, String sql, Object... params) {
        if (pagination != null) {
            Session session = this.getSession();
            SQLQuery query;
            if (pagination.getTotalCount() <= 0) {
                int n = sql.toLowerCase().lastIndexOf("order");
                query = session.createSQLQuery("select count(*) from (" + (n > 0 ? sql.substring(0, n) : sql) + ") as tt");
                this.setParameters(query, params);
                pagination.setTotalCount(((Number) query.uniqueResult()).intValue());
            }

            if (pagination.getPageNo() < 1) {
                pagination.setPageNo(1);
            }

            if (pagination.getPageSize() < 1) {
                pagination.setPageSize(10);
            }

            pagination.setPageCount((pagination.getTotalCount() + pagination.getPageSize() - 1) / pagination.getPageSize());
            query = session.createSQLQuery(sql);
            this.setParameters(query, params);
            query.setResultTransformer(new MapTransformer());
            query.setFirstResult(pagination.getPageSize() * (pagination.getPageNo() - 1));
            query.setMaxResults(pagination.getPageSize());
            pagination.setResultList(query.list());
        }
    }

    protected void setParameters(Query query, Object[] params) {
        if (params != null) {
            int n = 1;
            Object[] arr$ = params;
            int len$ = params.length;

            for (int i$ = 0; i$ < len$; ++i$) {
                Object p = arr$[i$];
                String x = "p" + n++;
                if (p != null && !(p instanceof String)) {
                    if (p instanceof Integer) {
                        query.setInteger(x, ((Integer) p).intValue());
                    } else if (p instanceof Long) {
                        query.setLong(x, ((Long) p).longValue());
                    } else if (p instanceof Float) {
                        query.setFloat(x, ((Float) p).floatValue());
                    } else if (p instanceof Double) {
                        query.setDouble(x, ((Double) p).doubleValue());
                    } else if (p instanceof Date) {
                        query.setTimestamp(x, (Date) p);
                    } else {
                        query.setParameter(x, p);
                    }
                } else {
                    query.setString(x, (String) p);
                }
            }

        }
    }

    protected Query getQuery(Session session, String sqlww, Object[] params, OrderSet orders, boolean qcount) {
        String sql = "from " + this.entityClass.getSimpleName();

        if (sqlww != null && sqlww.length() > 0) {
            sql = sql + " where " + sqlww;
        }

        if (qcount) {
            sql = "select count(*) " + sql;
        } else if (orders != null) {
            sql = sql + orders.toSql();
        }

        Query query = session.createQuery(sql.toString());
        this.setParameters(query, params);
        return query;
    }

    protected String objectToSql(Object obj, List<Object> params, String alias) {
        if (obj == null) {
            return "";
        } else {
            StringBuilder sql = new StringBuilder();
            Field[] fields = obj.getClass().getDeclaredFields();
            Field[] arr$ = fields;
            int len$ = fields.length;

            for (int i$ = 0; i$ < len$; ++i$) {
                Field f = arr$[i$];
                f.setAccessible(true);
                Object v = null;

                try {
                    v = f.get(obj);
                } catch (IllegalAccessException var14) {
                    ;
                }

                if (v != null && (!(v instanceof String) || ((String) v).length() != 0)) {
                    if (f.getType().getName().startsWith("com.")) {
                        String ss = this.objectToSql(v, params, f.getName());
                        if (ss != null && ss.length() > 0) {
                            sql.append(" and ").append(ss);
                        }
                    } else {
                        String op = v instanceof String && ((String) v).indexOf("%") >= 0 ? "like" : "=";
                        sql.append(" and " + (alias == null ? "" : alias + ".") + f.getName() + " " + op + " :p" + (params.size() + 1));
                        params.add(v);
                    }
                }
            }

            if (sql.length() > 5) {
                sql.delete(0, 5);
            }

            return sql.toString();
        }
    }
}
